package awdc;

import java.net.*;
import java.util.regex.*;

class ComWorker implements Runnable {
	Command CaseCommand;
	NickList HubNicklist;
	Speaker Speak;
	Shara HShara;
	//Конструктор
	ComWorker (Command CaseCommand, NickList HubNicklist, Speaker Speak, Shara HShara) {
		this.CaseCommand = CaseCommand;
		this.HubNicklist = HubNicklist;
		this.Speak = Speak;
		this.HShara = HShara;
	}


	public void run(){
		//Здесь в зависимости от комманды должен выполняться какой-то из методов
		String ComName = CaseCommand.getCommandName();

		if (ComName.equals("$Search"))
			doSearch(CaseCommand.getParametrs());
		else if (ComName.equals("$NickList"))
			setNickList(CaseCommand.getParametrs());
		else if (ComName.equals("$OpList"))
			setOpList(CaseCommand.getParametrs());

		//System.out.println("End of ComWorking");
	}

	//Метод, выполняющий поиск
	void doSearch(ComParams Params){

		System.out.println("Doing search. Here are search parametrs:");
		SearchParams SParams = new SearchParams(Params);
		SParams.showSearchParams();
		HShara.doSearch(SParams);
	}



	//Метод, устанавливающий НикЛИст после получения его от хаба
	void setNickList(ComParams Params){
	//	this.HubNicklist=new
	}

	//Метод, устанавливающий лист операторов
	void setOpList(ComParams Params){
	}
}

//Класс, являющий собой параметры поиска
class SearchParams {
	InetSocketAddress ClientAddress;//IP и порт ищущего
	boolean SizeRestricted;
	boolean IsMinimumSize;
	int Size;
	int DataType;
	SearchPattern SPatterns;

	//Конструктор
	SearchParams(ComParams ParamString){
		String FirstParametr = ParamString.getParam();//IP + Port\
		String SecondParametr = ParamString.getNext().getParam();//searchstring

		Pattern P = Pattern.compile("(.*):(.*)");
		Matcher m = P.matcher(FirstParametr);
		if (m.matches()){
//			System.out.println("Comworker(): Port"+m.group(2)+" IP:"+m.group(1));
			int Port = Integer.parseInt(m.group(2));
			String Hostname = m.group(1);
			ClientAddress = new InetSocketAddress(Hostname,Port);
		}
		P = Pattern.compile("(.)\\?(.)\\?(.*)\\?(.)\\?(.*)");
		m = P.matcher(SecondParametr);
		if (m.matches()){
//			System.out.println("Comworker():groups: 1:"+m.group(1)+" 2:"+m.group(2)+" 3:"+m.group(3)+" 4:"+m.group(4)+" 5:"+m.group(5));
			if (m.group(1).equals("T"))
				SizeRestricted=true;
			else
				SizeRestricted=false;
			if (m.group(2).equals("T"))
				IsMinimumSize = true;
			else
				IsMinimumSize = false;
			Size = Integer.parseInt(m.group(3));
			DataType = Integer.parseInt(m.group(4));

			//Распарсиваем поисковый паттерн
			String Patterns = m.group(5);
			P = Pattern.compile("([^\\$]*)(\\$(.*)|)");
			int flag = 0;
			int first = 1;
			SearchPattern Temp,Hlp;
			Temp = Hlp = null;
			while (flag != 1){
				m = P.matcher(Patterns);
				if (m.matches()){
					if (first ==1){
						SPatterns = new SearchPattern(m.group(1));
						Temp = SPatterns;
						Hlp = SPatterns;
						first = 0;
					} else {
						Hlp = Temp.getNext();
						Hlp = new SearchPattern(m.group(1));
						Temp.setNext(Hlp);
						Temp = Temp.getNext();
					}
					if (!(Pattern.matches("\\$.*",m.group(2)))) {
						flag = 1;
					} else
						Patterns = m.group(3);
				} else 
					flag = 1;
			}

		}
	}

	void showSearchParams(){
		System.out.println(ClientAddress);
		System.out.println(SizeRestricted);
		System.out.println(IsMinimumSize);
		System.out.println(Size);
		System.out.println(DataType);
		SPatterns.showSearchPattern();
	}
	//Следующие методы только для возвращения значений
	boolean getSizeRestricted(){
		return SizeRestricted;
	}

	boolean getIsMinimumSize(){
		return IsMinimumSize;
	}

	int getSize(){
		return Size;
	}

	int getDataType(){
		return DataType;
	}

	InetSocketAddress getClientAddress(){
		return ClientAddress;
	}

	SearchPattern getSPatterns(){
		return SPatterns;
	}
}

class SearchPattern {
	String OnePattern;
	SearchPattern Next;
	//Конструктор
	SearchPattern(String OnePattern){
		this.OnePattern = OnePattern;
		Next = null;
	}
	SearchPattern getNext(){
		return Next;
	}

	String getPattern(){
		return OnePattern;
	}
	void showSearchPattern(){
		System.out.println(OnePattern);
		if (Next != null)
			Next.showSearchPattern();
	}
	void setNext(SearchPattern Next){
		this.Next = Next;
	}
}
